package com.example.apitesttool.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * HTTP 请求执行工具
 * 
 * 提供基础的 HTTP 请求执行能力，支持 GET、POST、PUT、DELETE、PATCH 等方法。
 * 自动注入固定参数，并提供详细的请求和响应日志。
 * 
 * 特性：
 * - 支持所有常见的 HTTP 方法
 * - 自动注入固定参数（如 App-Key、Authorization）
 * - JSON 请求体自动处理
 * - 详细的请求响应日志
 * - 错误处理和异常捕获
 * 
 * @author liuxy
 * @version 1.0.0
 */
@Service
public class HttpRequestExecutor {
    
    private static final Logger logger = LoggerFactory.getLogger(HttpRequestExecutor.class);
    
    private final FixedParameterManager fixedParameterManager;
    private final ObjectMapper objectMapper;
    
    @Value("${api.base.url:http://localhost:8080}")
    private String defaultBaseUrl;

    @Autowired
    public HttpRequestExecutor(FixedParameterManager fixedParameterManager) {
        this.fixedParameterManager = fixedParameterManager;
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 执行 HTTP GET 请求
     * 
     * @param baseUrl 基础 URL（可选，为空则使用默认配置）
     * @param path 请求路径
     * @param queryParams 查询参数
     * @param headers 请求头
     * @return HTTP 响应结果字符串
     */
    public String executeGet(String baseUrl, String path, Map<String, String> queryParams, Map<String, String> headers) {
        return executeHttpRequest("GET", baseUrl, path, queryParams, headers, null);
    }

    /**
     * 执行 HTTP POST 请求
     * 
     * @param baseUrl 基础 URL（可选，为空则使用默认配置）
     * @param path 请求路径
     * @param requestBodyJson 请求体 JSON 字符串
     * @param queryParams 查询参数
     * @param headers 请求头
     * @return HTTP 响应结果字符串
     */
    public String executePost(String baseUrl, String path, String requestBodyJson, Map<String, String> queryParams, Map<String, String> headers) {
        return executeHttpRequest("POST", baseUrl, path, queryParams, headers, requestBodyJson);
    }

    /**
     * 执行 HTTP PUT 请求
     * 
     * @param baseUrl 基础 URL（可选，为空则使用默认配置）
     * @param path 请求路径
     * @param requestBodyJson 请求体 JSON 字符串
     * @param queryParams 查询参数
     * @param headers 请求头
     * @return HTTP 响应结果字符串
     */
    public String executePut(String baseUrl, String path, String requestBodyJson, Map<String, String> queryParams, Map<String, String> headers) {
        return executeHttpRequest("PUT", baseUrl, path, queryParams, headers, requestBodyJson);
    }

    /**
     * 执行 HTTP DELETE 请求
     * 
     * @param baseUrl 基础 URL（可选，为空则使用默认配置）
     * @param path 请求路径
     * @param queryParams 查询参数
     * @param headers 请求头
     * @return HTTP 响应结果字符串
     */
    public String executeDelete(String baseUrl, String path, Map<String, String> queryParams, Map<String, String> headers) {
        return executeHttpRequest("DELETE", baseUrl, path, queryParams, headers, null);
    }

    /**
     * 执行 HTTP PATCH 请求
     * 
     * @param baseUrl 基础 URL（可选，为空则使用默认配置）
     * @param path 请求路径
     * @param requestBodyJson 请求体 JSON 字符串
     * @param queryParams 查询参数
     * @param headers 请求头
     * @return HTTP 响应结果字符串
     */
    public String executePatch(String baseUrl, String path, String requestBodyJson, Map<String, String> queryParams, Map<String, String> headers) {
        return executeHttpRequest("PATCH", baseUrl, path, queryParams, headers, requestBodyJson);
    }

    /**
     * 执行 HTTP 请求的核心方法
     * 
     * @param method HTTP 方法
     * @param baseUrl 基础 URL
     * @param path 请求路径
     * @param queryParams 查询参数
     * @param headers 请求头
     * @param requestBodyJson 请求体 JSON
     * @return 格式化的响应结果字符串
     */
    private String executeHttpRequest(String method, String baseUrl, String path, 
                                    Map<String, String> queryParams, Map<String, String> headers, 
                                    String requestBodyJson) {
        
        long startTime = System.currentTimeMillis();
        String actualBaseUrl = (baseUrl != null && !baseUrl.trim().isEmpty()) ? baseUrl.trim() : defaultBaseUrl;
        
        logger.info("开始执行 HTTP 请求: {} {}{}", method, actualBaseUrl, path);
        
        try {
            RequestSpecification request = RestAssured.given();
            request.baseUri(actualBaseUrl);

            // 注入所有已设置的固定参数作为 Header
            Map<String, String> fixedParams = fixedParameterManager.getAllParameters();
            if (!fixedParams.isEmpty()) {
                fixedParams.forEach(request::header);
                logger.debug("注入了 {} 个固定参数", fixedParams.size());
            }

            // 添加用户提供的 Header
            if (headers != null && !headers.isEmpty()) {
                headers.forEach(request::header);
                logger.debug("添加了 {} 个自定义请求头", headers.size());
            }

            // 添加查询参数
            if (queryParams != null && !queryParams.isEmpty()) {
                queryParams.forEach(request::queryParam);
                logger.debug("添加了 {} 个查询参数", queryParams.size());
            }

            // 处理请求体
            if (requestBodyJson != null && !requestBodyJson.trim().isEmpty()) {
                try {
                    // 验证 JSON 格式
                    objectMapper.readTree(requestBodyJson);
                    request.contentType(ContentType.JSON);
                    request.body(requestBodyJson);
                    logger.debug("设置 JSON 请求体，长度: {} 字符", requestBodyJson.length());
                } catch (Exception e) {
                    logger.warn("请求体不是有效的 JSON 格式，将作为纯文本处理: {}", e.getMessage());
                    request.contentType(ContentType.TEXT);
                    request.body(requestBodyJson);
                }
            }

            // 执行请求
            Response response = executeRequest(request, method, path);
            long duration = System.currentTimeMillis() - startTime;

            // 格式化响应结果
            String result = formatResponse(method, actualBaseUrl + path, response, duration);
            logger.info("HTTP 请求完成: {} {} - 状态码: {} - 耗时: {}ms", 
                       method, actualBaseUrl + path, response.getStatusCode(), duration);
            
            return result;

        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            String errorMessage = String.format("HTTP 请求失败: %s %s%s - 错误: %s - 耗时: %dms", 
                                               method, actualBaseUrl, path, e.getMessage(), duration);
            logger.error(errorMessage, e);
            return errorMessage;
        }
    }

    /**
     * 根据 HTTP 方法执行具体的请求
     */
    private Response executeRequest(RequestSpecification request, String method, String path) {
        switch (method.toUpperCase()) {
            case "GET":
                return request.get(path);
            case "POST":
                return request.post(path);
            case "PUT":
                return request.put(path);
            case "DELETE":
                return request.delete(path);
            case "PATCH":
                return request.patch(path);
            default:
                throw new IllegalArgumentException("不支持的 HTTP 方法: " + method);
        }
    }

    /**
     * 格式化 HTTP 响应结果
     */
    private String formatResponse(String method, String fullUrl, Response response, long duration) {
        StringBuilder result = new StringBuilder();
        
        result.append("=== HTTP 请求结果 ===\n");
        result.append("请求: ").append(method).append(" ").append(fullUrl).append("\n");
        result.append("状态码: ").append(response.getStatusCode()).append("\n");
        result.append("耗时: ").append(duration).append("ms\n");
        
        // 响应头
        result.append("响应头:\n");
        response.getHeaders().forEach(header -> 
            result.append("  ").append(header.getName()).append(": ").append(header.getValue()).append("\n"));
        
        // 响应体
        String responseBody = response.getBody().asString();
        result.append("响应体长度: ").append(responseBody.length()).append(" 字符\n");
        
        if (responseBody.length() > 0) {
            result.append("响应体内容:\n");
            // 如果响应体太长，进行截断
            if (responseBody.length() > 2000) {
                result.append(responseBody.substring(0, 2000)).append("\n... (响应体过长，已截断)");
            } else {
                result.append(responseBody);
            }
        } else {
            result.append("响应体为空");
        }
        
        return result.toString();
    }

    /**
     * 获取当前配置的默认基础 URL
     */
    public String getDefaultBaseUrl() {
        return defaultBaseUrl;
    }

    /**
     * 设置默认基础 URL（运行时动态修改）
     */
    public void setDefaultBaseUrl(String baseUrl) {
        if (baseUrl != null && !baseUrl.trim().isEmpty()) {
            this.defaultBaseUrl = baseUrl.trim();
            logger.info("更新默认基础 URL: {}", this.defaultBaseUrl);
        }
    }
}

